package com.baasp.gateway.filter;

import com.baasp.gateway.utils.TokenUtils;
import com.google.gson.JsonObject;
import io.jsonwebtoken.Claims;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.support.DefaultServerRequest;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;

/**
 * Created by simon on 2019/5/23.
 */
@Component
public class AuthFilter implements GatewayFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain filterChain) {
        ServerRequest serverRequest = new DefaultServerRequest(exchange);
        String authHeader = null;
        String uri = exchange.getRequest().getURI().getPath();
        if(null!=serverRequest.headers().asHttpHeaders().get("Authorization")
                &&serverRequest.headers().asHttpHeaders().get("Authorization").size()>0){
            authHeader = serverRequest.headers().asHttpHeaders().get("Authorization").get(0);
        }

        if(!(serverRequest.headers().asHttpHeaders().get("x-app")+"").contains("1")
                && !uri.equals("/api/user/upload")
                && !uri.equals("/api/user/uploadElevators")
                && !uri.equals("/api/user/uploadPlanDetail")
                && !uri.equals("/api/user/uploadParty")
                && !uri.equals("/api/user/uploadUser")
                && !uri.equals("/api/role/queryList")
                && !uri.equals("/api/user/uploadbig")
                && !uri.startsWith("/api/userElevator")
                && !uri.equals("/api/appraisal/add")
                && !uri.equals("/api/appraisal/good")
                && !uri.contains("/api/user/deleteUpload/")
                && !uri.equals("/api/appraisal/getElevatorAppraisal")
                && !uri.equals("/api/resetPassword")
                && !uri.equals("/api/planDetail/importExcel")
                && !uri.equals("/api/checkItem/importExcel")
                && !uri.equals("/api/checkItem/uploadExcel")
                && !uri.equals("/api/party/queryPartyByPartyLevel")
                && !uri.equals("/api/paperlessMaint/add")
                ){
            if (authHeader == null || !authHeader.startsWith("Bearer ")) {
                ServerHttpResponse response = exchange.getResponse();
                JsonObject message = new JsonObject();
                message.addProperty("status", 401);
                message.addProperty("message", "认证失败");
                byte[] bits = message.toString().getBytes(StandardCharsets.UTF_8);
                DataBuffer buffer = response.bufferFactory().wrap(bits);
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                //指定编码，否则在浏览器中会中文乱码
                response.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");
                return response.writeWith(Mono.just(buffer));
            }

            try {
                Claims claims = TokenUtils.parseToken(authHeader);
                serverRequest.attributes().put("claims", claims);
            } catch (final Exception e) {
                ServerHttpResponse response = exchange.getResponse();
                JsonObject message = new JsonObject();
                message.addProperty("message", "认证失败");
                message.addProperty("status", 401);
                byte[] bits = message.toString().getBytes(StandardCharsets.UTF_8);
                DataBuffer buffer = response.bufferFactory().wrap(bits);
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                //指定编码，否则在浏览器中会中文乱码
                response.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");
                return response.writeWith(Mono.just(buffer));
            }
        }
        return filterChain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return -100;
    }
}
